/******************************************************
 * @file reader_page.c
 * @author Destiny 
 * @brief 电子书阅读程序
 * @version 0.1
 * @date 2024-07-18
 *****************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdlib.h>
#include <string.h>

/* Private Includes ----------------------------------------------------------*/
#include "config.h"
#include "render.h"
#include "file.h"
#include "page_manager.h"

/* Private typedef -----------------------------------------------------------*/
/*页面管理*/
typedef struct ReaderPage
{  
    uint8_t *pucFileCurPagePos;   /*当前页面第一个字符在文件中的位置*/
    struct ReaderPage *ptNextPage;     
    struct ReaderPage *ptPrePage;
}T_ReaderPage,*PT_ReaderPage;

/* Private Define ------------------------------------------------------------*/
#define TXT_ICON_WIDTH  40                                 /*子目录与文件图标的宽*/
#define TXT_ICON_HEIGHT TXT_ICON_WIDTH                     /*子目录与文件图标的高*/
#define TXT_NAME_HEIGHT 20                                 /*子目录与文件名称的高*/
#define TXT_NAME_WIDTH (TXT_ICON_HEIGHT + TXT_NAME_HEIGHT) /*子目录与文件名称的宽*/
#define TXT_ALL_WIDTH TXT_NAME_WIDTH
#define TXT_ALL_HEIGHT TXT_ALL_WIDTH
#define MIN_ICON_SPACING 10                      /*图标最小间距*/

#define TXT_ICON_INDEX_BASE 1000                        /*目录文件起始索引，大于为目录文件，小于为菜单选项*/
/* Extern variables ---------------------------------------------------------*/
extern int g_iReaderFontSize;
/* Private variables ---------------------------------------------------------*/
static PT_ReaderPage g_ptReaderPagehead = NULL;    /*第一页*/
static PT_ReaderPage g_ptReaderPageCur  = NULL;    /*当前显示的页面*/
static uint8_t *g_pucFileStart = NULL;       /*文件开始，去掉文件头，为NULL时表示未打开txt文件*/
static uint8_t *g_pucFileEnd;                /*文件结尾*/

static T_Layout g_atMenuIconsLayout[] = {
    //	{0, 0, 0, 0, "return.bmp"},
    {0, 0, 0, 0, "/opt/icon/Menu/return.bmp"},
    {0, 0, 0, 0, "/opt/icon/Menu/select.bmp"},
    {0, 0, 0, 0, "/opt/icon/Menu/shotscreen.bmp"},
    {0, 0, 0, 0, "/opt/icon/Menu/pre.bmp"},
    {0, 0, 0, 0, "/opt/icon/Menu/next.bmp"},
    {0, 0, 0, 0, "/opt/icon/Menu/home.bmp"},
    {0, 0, 0, 0, NULL},
};

/*页面菜单栏布局*/
static T_PageLayout g_tReaderPageMenuIconsLayout = {
    .iMaxTotalBytes = 0,
    .atLayout = g_atMenuIconsLayout,
};

static char *g_strTXTFileIconName   = "/opt/icon/file_types/file_txt.bmp";
static char *g_strDefaultFileIconName   = "/opt/icon/file_types/file_default.bmp";
static T_PixelDatas g_tTXTFileIconPixelDatas;
static T_PixelDatas g_tDefaultFileIconPixelDatas;

static T_Layout *g_tTXTFileLayout;
/*页面子目录与文件布局*/
static T_PageLayout g_tReaderPageTXTLayout = {
    .iMaxTotalBytes = 0,
    //.atLayout       = g_tTXTFileLayout,
};
/*每行、列的文件数*/
static int g_iDirFileNumPerCol, g_iDirFileNumPerRow;

static PT_DirContent *g_aptDirContents; /*用于存放读取的当前目录下的子目录与文件*/
static int g_iDirContentsNumber;        /*当前目录下子目录与文件的数量*/
static int g_iStartIndex = 0;           /*当前页面显示的第一个文件在所有文件中的索引*/

static char g_strCurDir[256] = READER_DIR; /*当前目录*/      
static T_FileMap g_tFileMap;               /*文件*/


/* Private Function Prototypes -----------------------------------------------*/
/**
 * @brief 将页面插入链表尾部
 * 
 * @param ptReaderPage 页面管理结构体
*/
static void SaveCurPage(PT_ReaderPage ptReaderPage)
{
	PT_ReaderPage ptTmp;
    
	if (!g_ptReaderPagehead)
	{
		g_ptReaderPagehead        = ptReaderPage;
		ptReaderPage->ptNextPage  = NULL;
        ptReaderPage->ptPrePage   = NULL;
        
	}
	else
	{
		ptTmp = g_ptReaderPagehead;
		while (ptTmp->ptNextPage)
		{
			ptTmp = ptTmp->ptNextPage;
		}
		ptTmp->ptNextPage	  = ptReaderPage;
		ptReaderPage->ptNextPage = NULL;
        ptReaderPage->ptPrePage  = ptTmp;
	} 
}

/**
 * @brief 新建一页
 * 
 * @param pucFileCurPagePos 当前页面第一个字符在文件中的位置
 * @return int 成功：0;失败：其他
*/
static int CreatOnePage( uint8_t *pucFileCurPagePos)
{
    PT_ReaderPage ptReaderPage;
    /*TXT文件已读完*/
    if(pucFileCurPagePos >= g_pucFileEnd)
    {
        return -1;
    }
    /*当前页不是链表中的最后一页*/
    if(g_ptReaderPageCur->ptNextPage)
    {
        return 0;
    }
    /*新建一页*/
    ptReaderPage = malloc(sizeof(T_ReaderPage));
    if(!ptReaderPage)
    {
        return -2;
    }
    ptReaderPage->pucFileCurPagePos = pucFileCurPagePos;
    
    SaveCurPage(ptReaderPage);
    return 0;  
}

/**
 * @brief 销毁页面链表
*/
static void DestroyAllPage()
{
    PT_ReaderPage ptPageCur = g_ptReaderPagehead;
    PT_ReaderPage ptPageNext;
	while (ptPageCur)
	{
        ptPageNext = ptPageCur->ptNextPage;
        free(ptPageCur);
        ptPageCur = ptPageNext;
	}
}

/**
 * @brief 初始化当前TXT文件
 * 
 * @param ptPageVideoMem 显示缓冲区
 * @param strTmp 文件路径
 * @return int 成功：0;失败：其他
*/
static int EnterCurTXTFile(PT_VideoMem ptPageVideoMem,char *strTmp)
{
    int iError;
    PT_ReaderPage ptReaderPage= malloc(sizeof(T_ReaderPage));

    g_ptReaderPageCur = ptReaderPage;

    strncpy(g_tFileMap.strFileName, strTmp, 256);
	g_tFileMap.strFileName[255] = '\0';

    strncpy(g_strCurDir, strTmp, 256);
	g_strCurDir[255] = '\0';

    iError = MapFile(&g_tFileMap);
	if (iError)
	{
		DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"MapFile %s error!\n", strTmp);
		return -1;
	}
	/*得到文件起始地址与结束地址*/
	g_pucFileStart = g_tFileMap.pucFileMapMem + 3; 
    ptReaderPage->pucFileCurPagePos = g_pucFileStart;    
	g_pucFileEnd   = g_tFileMap.pucFileMapMem + g_tFileMap.iFileSize;

    /*保存当前页信息*/
    SaveCurPage(ptReaderPage);
    /*构造当前页*/
    iError = CreatOnePage(GetOnePageFrmTXT(ptPageVideoMem,&g_tReaderPageTXTLayout,\
    g_ptReaderPageCur->pucFileCurPagePos,g_pucFileEnd,g_iReaderFontSize));
    if (iError < 0)
    {
        if(iError==-1)
        {
            DBG_PRINTF(DLOG_LVL_INFO,DLOG_TAG," Is the Last Page!\n");
        }
        else
        {                                   
            DBG_PRINTF(DLOG_LVL_INFO,DLOG_TAG,"CreatOnePage error!\n");
            return -1;
        }
    }
    return 0;
}

/**
 * @brief 退出当前TXT文件
 * 
 * @return int 成功：0;失败：其他
*/
static int QuitCurTXTFile()
{
    char *pcTmp;
    int iError;
    
       /*找到最后一个'/'的指针，并将其去除*/
    pcTmp = strrchr(g_strCurDir, '/');
    *pcTmp = '\0';
    /*获得新目录下的子目录与文件*/
    iError = GetDirContents(g_strCurDir, &g_aptDirContents, &g_iDirContentsNumber);
    if (iError)
    {
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"GetDirContents error!\n");
        return -1;
    }
    g_iStartIndex = 0;
    /*表退出阅读模式*/
    g_pucFileStart = NULL;
    /*重新生成文件目录图标*/
    DestroyAllPage();
    UnMapFile(&g_tFileMap);
    g_ptReaderPagehead = NULL;
    g_ptReaderPageCur = NULL;
    return 0;
    
}

/**
 * @brief 计算当前目录下的文件与子目录图标位置
*/
static void CalcReaderPageTXTFileLayout(void)
{
    int iXres, iYres, iBpp;
    int iTopLeftX, iTopLeftY;
    int iTopLeftXBak;
    int iBotRightX, iBotRightY;
    int iIconWidth, iIconHeight;
    int iNumPerCol, iNumPerRow;
    int iDeltaX, iDeltaY;
    int i, j, k = 0;

    GetDispResolution(&iXres, &iYres, &iBpp);
    /*确定文件显示区域*/
    if (iXres < iYres)
    {

        iTopLeftX = 0;
        iBotRightX = iXres - 1;
        iTopLeftY = g_atMenuIconsLayout[0].iBotRightY + 1;
        iBotRightY = iYres - 1;
    }
    else
    {

        iTopLeftX = g_atMenuIconsLayout[0].iBotRightX + 1;
        iBotRightX = iXres - 1;
        iTopLeftY = 0;
        iBotRightY = iYres - 1;
    }
    /*确定图标大小*/
    iIconWidth = TXT_NAME_WIDTH;
    iIconHeight = iIconWidth;

    /*计算区域内每行可以显示多少个文件图标*/
    iNumPerRow = (iBotRightX - iTopLeftX + 1) / iIconWidth;

    /*计算得到图标间隔大小，间隔不能小于MIN_ICON_SPACING*/
    while (1)
    {
        iDeltaX = (iBotRightX - iTopLeftX + 1) - iIconWidth * iNumPerRow;
        if ((iDeltaX / (iNumPerRow + 1)) < MIN_ICON_SPACING)
            iNumPerRow--;
        else
            break;
    }
    /*计算区域内每列可以显示多少个文件图标*/
    iNumPerCol = (iBotRightY - iTopLeftY + 1) / iIconHeight;
    while (1)
    {
        iDeltaY = (iBotRightY - iTopLeftY + 1) - iIconHeight * iNumPerCol;
        if ((iDeltaY / (iNumPerCol + 1)) < MIN_ICON_SPACING)
            iNumPerCol--;
        else
            break;
    }

    iDeltaX = iDeltaX / (iNumPerRow + 1);
    iDeltaY = iDeltaY / (iNumPerCol + 1);

    g_iDirFileNumPerRow = iNumPerRow;
    g_iDirFileNumPerCol = iNumPerCol;

    /* 可以显示 iNumPerRow * iNumPerCol个"目录或文件"
     * 分配"两倍+1"的T_Layout结构体: 一个用来表示图标,另一个用来表示名字
     * 最后一个用来存NULL,借以判断结构体数组的末尾
     */
    g_tTXTFileLayout = malloc(sizeof(T_Layout) * (2 * iNumPerRow * iNumPerCol + 1));
    if (NULL == g_tTXTFileLayout)
    {
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"malloc error!\n");
        return;
    }
    /*确定文件显示区域大小，以及图标字节数*/
    g_tReaderPageTXTLayout.iTopLeftX = iTopLeftX;
    g_tReaderPageTXTLayout.iBotRightX = iBotRightX;
    g_tReaderPageTXTLayout.iTopLeftY = iTopLeftY;
    g_tReaderPageTXTLayout.iBotRightY = iBotRightY;
    g_tReaderPageTXTLayout.iBpp = iBpp;
    g_tReaderPageTXTLayout.atLayout = g_tTXTFileLayout;
    g_tReaderPageTXTLayout.iMaxTotalBytes = TXT_ALL_WIDTH * TXT_ALL_HEIGHT * iBpp / 8;

    /*计算每个图标的显示坐标*/
    iTopLeftX += iDeltaX;
    iTopLeftY += iDeltaY;
    iTopLeftXBak = iTopLeftX;
    for (i = 0; i < iNumPerCol; i++)
    {
        for (j = 0; j < iNumPerRow; j++)
        {

            g_tTXTFileLayout[k].iTopLeftX = iTopLeftX + (TXT_NAME_WIDTH - TXT_ICON_WIDTH) / 2;  /*左上角图标坐标*/
            g_tTXTFileLayout[k].iBotRightX = g_tTXTFileLayout[k].iTopLeftX + TXT_ICON_WIDTH - 1; /*右下角图标坐标*/
            g_tTXTFileLayout[k].iTopLeftY = iTopLeftY;
            g_tTXTFileLayout[k].iBotRightY = iTopLeftY + TXT_ICON_HEIGHT - 1;

            g_tTXTFileLayout[k + 1].iTopLeftX = iTopLeftX; /*左上文件名坐标*/
            g_tTXTFileLayout[k + 1].iBotRightX = iTopLeftX + TXT_NAME_WIDTH - 1;
            g_tTXTFileLayout[k + 1].iTopLeftY = g_tTXTFileLayout[k].iBotRightY + 1;
            g_tTXTFileLayout[k + 1].iBotRightY = g_tTXTFileLayout[k + 1].iTopLeftY + TXT_NAME_HEIGHT - 1;

            iTopLeftX += TXT_ALL_WIDTH + iDeltaX;
            k += 2;
        }
        iTopLeftX = iTopLeftXBak; /*计算完一行，开始新的一行*/
        iTopLeftY += TXT_ALL_HEIGHT + iDeltaY;
    }
    /*表示结尾*/
    g_tTXTFileLayout[k].iTopLeftX = 0;
    g_tTXTFileLayout[k].iBotRightX = 0;
    g_tTXTFileLayout[k].iTopLeftY = 0;
    g_tTXTFileLayout[k].iBotRightY = 0;
    g_tTXTFileLayout[k].strIconName = NULL;
}

/**
 * @brief  获得输入事件，返回值为被选择的图标索引，用于菜单栏
 * 
 * @param ptPageLayout 页面布局区域信息
 * @param ptInputEvent 输入事件信息
 * @return int 成功：被选择的图标索引;失败：-1
*/
static int ReaderPageGetInputEvent(PT_PageLayout ptPageLayout, PT_InputEvent ptInputEvent)
{
    return GenericGetInputEvent(ptPageLayout, ptInputEvent);
}

/**
 * @brief 获得输入事件，返回值为被选择的图标索引，用于文件图标
 * 
 * @param ptPageLayout 页面布局区域信息
 * @param ptInputEvent 输入事件信息
 * @return int 成功：被选择的图标索引;失败：-1
*/
static int GetInputPositionInPageLayout(PT_PageLayout ptPageLayout, PT_InputEvent ptInputEvent)
{
    int i = 0;
    PT_Layout atLayout = ptPageLayout->atLayout;

    while (atLayout[i].iBotRightY)
    {
        if ((ptInputEvent->iX >= atLayout[i].iTopLeftX) && (ptInputEvent->iX <= atLayout[i].iBotRightX) &&
            (ptInputEvent->iY >= atLayout[i].iTopLeftY) && (ptInputEvent->iY <= atLayout[i].iBotRightY))
        {

            return i;
        }
        else
        {
            i++;
        }
    }

    return -1;
}

/**
 * @brief 得到图标文件
 * 
 * @param ptPageLayout 页面布局信息
 * @return int 成功：0;失败：其他
*/
static int GenerateDirAndFileIcons(PT_PageLayout ptPageLayout)
{
    int iError;
    int iXres, iYres, iBpp;
    int iHeight,iWidth;
    PT_Layout atLayout = ptPageLayout->atLayout;
    GetDispResolution(&iXres, &iYres, &iBpp);
    iHeight = atLayout[0].iBotRightY - atLayout[0].iTopLeftY + 1;
    iWidth  = atLayout[0].iBotRightX - atLayout[0].iTopLeftX+ 1;
    iError = GetIcons(&g_tTXTFileIconPixelDatas,g_strTXTFileIconName,ptPageLayout->iMaxTotalBytes,iHeight,iWidth,iBpp);
    if(iError < 0)
    {   
        return -1;
    }
    iError = GetIcons(&g_tDefaultFileIconPixelDatas,g_strDefaultFileIconName,ptPageLayout->iMaxTotalBytes,iHeight,iWidth,iBpp);
    if(iError < 0)
    {   
        return -1;
    }
    return 0;
}

/**
 * @brief 生成文件与子目录图标
 * 
 * @param iStartIndex 当前页面显示的第一个文件在所有文件中的索引
 * @param iDirContentsNumber 文件总数
 * @param aptDirContents     文件目录信息
 * @param ptVideoMem         缓冲区
 * @return int 成功：0;失败：其他
*/
static int GenerateReaderPageDirAndFile(int iStartIndex, int iDirContentsNumber, PT_DirContent *aptDirContents, PT_VideoMem ptVideoMem)
{
    int iError;
    int i, j, k = 0;
    int iDirContentIndex = iStartIndex;
    PT_PageLayout ptPageLayout = &g_tReaderPageTXTLayout;
    PT_Layout atLayout = ptPageLayout->atLayout;

    // iHeight = atLayout[0].iBotRightY - atLayout[0].iTopLeftY + 1;
    // iWidth  = atLayout[0].iBotRightX - atLayout[0].iTopLeftX+ 1;
    (void)iError;
    /*清空矩形区域*/
    ClearRectangleInVideoMem(ptPageLayout->iTopLeftX, ptPageLayout->iTopLeftY, ptPageLayout->iBotRightX, ptPageLayout->iBotRightY, ptVideoMem, g_BackGroundColor);
    /*设置字体大小*/
    SetFontSize(atLayout[1].iBotRightY - atLayout[1].iTopLeftY - 5);

    for (i = 0; i < g_iDirFileNumPerCol; i++)
    {
        for (j = 0; j < g_iDirFileNumPerRow; j++)
        {
            /*当前文件索引小于文件数*/
            if (iDirContentIndex < iDirContentsNumber)
            {
                switch (aptDirContents[iDirContentIndex]->eFileType)
                {

                case FILETYPE_FILE_TXT:
                    /*TXT文件*/

                    PicMerge(atLayout[k].iTopLeftX, atLayout[k].iTopLeftY, &g_tTXTFileIconPixelDatas, &ptVideoMem->tPixelDatas);
                    break;
                case FILETYPE_DIR:
                case FILETYPE_FILE_BMP:
                case FILETYPE_FILE_JPEG:
                case FILETYPE_FILE_PNG:
                case FILETYPE_FILE_DEFAULT:
                    /*默认*/
                    PicMerge(atLayout[k].iTopLeftX, atLayout[k].iTopLeftY, &g_tDefaultFileIconPixelDatas, &ptVideoMem->tPixelDatas);
                    break;
                default:
                    break;
                }
                k++;

                /*显示文件名*/
                iError = MergerStringToCenterOfRectangleInVideoMem(atLayout[k].iTopLeftX, atLayout[k].iTopLeftY, atLayout[k].iBotRightX,
                                                                   atLayout[k].iBotRightY, (uint8_t *)aptDirContents[iDirContentIndex]->strName, ptVideoMem);

                k++;

                iDirContentIndex++;
            }
            else
            {
                break;
            }
        }
        if (iDirContentIndex >= iDirContentsNumber)
        {
            break;
        }
    }
    return 0;
}

/**
 * @brief 重新加载文件图标
 * 
 * @param ptVideoMem 显示缓冲区
 * @return int 成功：0;失败：其他
*/
static int ReloadFileIcons(PT_VideoMem ptVideoMem)
{
    int iError;
    iError = GetDirContents(g_strCurDir, &g_aptDirContents, &g_iDirContentsNumber);
    if (iError)
    {
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"GetDirContents error!\n");
        return iError;
    }
    iError = GenerateReaderPageDirAndFile(g_iStartIndex, g_iDirContentsNumber, g_aptDirContents, ptVideoMem);
    return iError;
}

/**
 * @brief 显示页面
 * 
 * @param ptPageLayout 页面布局信息
 * @param ptVideoMem 显示缓冲区
*/
static void ShowReaderPage(PT_PageLayout ptPageLayout,PT_VideoMem ptVideoMem)
{
    int iError;
    int iNumMenu;
    (void)iError;


    /*图标位置计算*/
    if(!ptPageLayout->iMaxTotalBytes)
    {
        iNumMenu = (sizeof(g_atMenuIconsLayout)/sizeof(T_Layout) - 1);
        CalculatePageMenusLayout(ptPageLayout,iNumMenu);
        CalcReaderPageTXTFileLayout();
    }
    /* 目录和文件的图标未生成 */
    if (!g_tTXTFileIconPixelDatas.aucPixelDatas)
    {
        GenerateDirAndFileIcons(&g_tReaderPageTXTLayout);
    }
    /*将数据写入缓冲区*/
    iError = GeneratePage(ptPageLayout, ptVideoMem);
    iError = GenerateReaderPageDirAndFile(g_iStartIndex, g_iDirContentsNumber, g_aptDirContents, ptVideoMem);

    /*缓冲区数据写入显示设备显存*/
    FlushVideoMemToDev(ptVideoMem);
}
/**
 * @brief 图标被选择时，改变其图像数据
 * 
 * @param iDirFileIndex 图标索引
 * @param ptVideoMem 显示缓冲区
*/
static void SelectDirFileIcon(int iDirFileIndex,PT_VideoMem ptVideoMem)
{

    /*去掉最后一位*/
    iDirFileIndex = iDirFileIndex & ~1;
    /*得到索引*/
   
    /*文件被选中，颜色取反*/
    InvertButton(&g_tTXTFileLayout[iDirFileIndex],ptVideoMem);
    InvertButton(&g_tTXTFileLayout[iDirFileIndex + 1],ptVideoMem);
}

/**
 * @brief 电子书阅读页面逻辑
 * 
 * @param ptParentPageParams 父页面参数
*/
static void ReaderPageRun(PT_PageParams ptParentPageParams)
{
    int iIndex;

    char strTmp[256];
    T_InputEvent tInputEvent;
    T_InputEvent tInputEventPrePress;

    int bIconPressed = 0;

    int iIndexPressed = -1;

    int iSelectFlag = 0;
    int iSelectedFileIndex[256] = {0};
    int iSelectedFileNum = 0;

    int iDirFileContentIndex;

    int iError;

    T_PageParams tPageParams;
    tPageParams.iPageID = ID("Reader");

    PT_VideoMem ptDevVideoMem;
    PT_VideoMem ptPageVideoMem;
    /*申请获得缓冲区*/
    ptPageVideoMem = GetVideoMem(tPageParams.iPageID, 1);
    if (ptPageVideoMem == NULL)
    {
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"can't get video mem for Reader page!\n");
        return;
    }
    /*得到显示设备显存地址*/
    ptDevVideoMem = GetDevVideoMem();

    /*时间时间初始化*/
    tInputEventPrePress.tTime.tv_sec = 0;
    tInputEventPrePress.tTime.tv_usec = 0;


    /*读取当前目录下的文件与子目录*/
    iError = GetDirContents(g_strCurDir, &g_aptDirContents, &g_iDirContentsNumber);
    if (iError)
    {
        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"GetDirContents error!\n");
        goto exit_process;
    }
    /*显示页面数据*/
    ShowReaderPage(&g_tReaderPageMenuIconsLayout,ptPageVideoMem);
    
    /* 父页面为browse，直接显示txt文件内容 */
    if(ptParentPageParams->iPageID == ID("browse"))
    {
        EnterCurTXTFile(ptPageVideoMem,ptParentPageParams->strCurPictureFile); 
    }   
       
    while (1)
    {  
        /*读取输入事件,获取按钮索引*/
        iIndex = ReaderPageGetInputEvent(&g_tReaderPageMenuIconsLayout, &tInputEvent);
          
        /* 触点不在菜单图标上, 则判断是在哪一个"目录和文件"上 */
        if (iIndex == -1)
        {
            iIndex = GetInputPositionInPageLayout(&g_tReaderPageTXTLayout, &tInputEvent);
            if (iIndex != -1)
            {
                if (g_iStartIndex + iIndex / 2 < g_iDirContentsNumber) /* 判断这个触点上是否有图标 */
                    iIndex += TXT_ICON_INDEX_BASE;
                else
                    iIndex = -1;
            }
        }
        /*按键被松开*/
        if (tInputEvent.iPressure == 0)
        {
            /*如果没有图标被按下，不做处理*/
            if (!bIconPressed)
            {
                goto mouse;
            }
            bIconPressed = 0;
            /*按下的为菜单图标*/
            if (iIndexPressed < TXT_ICON_INDEX_BASE)
            {
                
                /*按下和松开的是同一个图标*/
                if (iIndexPressed == iIndex)
                {
                    switch (iIndex)
                    {
                    case 0: /* 返回按钮 */
                    {
                        if(ptParentPageParams->iPageID == ID("browse"))
                        {
                            QuitCurTXTFile();
                            goto exit_process;
                        }
                        /*为最顶层*/
                        if (0 == strcmp(g_strCurDir, READER_DIR))
                        {
                            FreeDirContents(g_aptDirContents, g_iDirContentsNumber);
                            /*跳转到指定位置*/
                            goto exit_process;
                        }
                        else
                        {
                            iError = GenerateReaderPageDirAndFile(g_iStartIndex, g_iDirContentsNumber, g_aptDirContents, ptPageVideoMem);
                            QuitCurTXTFile();
                        }  
                        InvertButton(&g_atMenuIconsLayout[iIndexPressed],ptPageVideoMem); 
                        break;
                    }
                    case 1: /* "选择"按钮 */
                    {
                        if(iSelectFlag)
                        {
                            iSelectFlag = 0;
                            InvertButton(&g_atMenuIconsLayout[iIndexPressed],ptPageVideoMem);
                            while(iSelectedFileNum)
                            {
                                iSelectedFileNum--;
                                SelectDirFileIcon(iSelectedFileIndex[iSelectedFileNum] - TXT_ICON_INDEX_BASE,ptPageVideoMem);
                            }
                        }
                        else
                        {
                            iSelectFlag = 1;
                            InvertButton(&g_atMenuIconsLayout[iIndex],ptPageVideoMem);
                        }
                        
                        break;
                    } 
                    case 2:/* 截屏按钮 */
                    {
                        InvertButton(&g_atMenuIconsLayout[iIndexPressed],ptPageVideoMem);
                        SavePixelDataAsBmp(&ptDevVideoMem->tPixelDatas);
                        break;
                    }
                    case 3: /* "上一页" */
                    {
                        InvertButton(&g_atMenuIconsLayout[iIndexPressed],ptPageVideoMem);
                        if(g_pucFileStart)
                        {
                            if(g_ptReaderPageCur->ptPrePage)                            {
                                g_ptReaderPageCur = g_ptReaderPageCur->ptPrePage;
                                
                               GetOnePageFrmTXT(ptPageVideoMem,&g_tReaderPageTXTLayout,\
                                g_ptReaderPageCur->pucFileCurPagePos,g_pucFileEnd,g_iReaderFontSize);
                            }
                        }
                        else
                        {
                            /*计算当前页第一个图标索引值*/
                            g_iStartIndex -= g_iDirFileNumPerCol * g_iDirFileNumPerRow;
                            if (g_iStartIndex >= 0)
                            {
                                /*若满足翻页要求，则重新生成*/
                                iError = GenerateReaderPageDirAndFile(g_iStartIndex, g_iDirContentsNumber, g_aptDirContents, ptPageVideoMem);
                            }
                            else
                            {
                                /*不满足翻页要求，不做改变*/
                                g_iStartIndex += g_iDirFileNumPerCol * g_iDirFileNumPerRow;
                            }
                        }
                        break;
                    }
                    case 4: /* "下一页" */
                    {
                        InvertButton(&g_atMenuIconsLayout[iIndexPressed],ptPageVideoMem);
                        if (g_pucFileStart)
                        {
                            if (g_ptReaderPageCur->ptNextPage)
                            {
                                g_ptReaderPageCur = g_ptReaderPageCur->ptNextPage;
                                iError = CreatOnePage(GetOnePageFrmTXT(ptPageVideoMem, &g_tReaderPageTXTLayout,\
                                g_ptReaderPageCur->pucFileCurPagePos, g_pucFileEnd, g_iReaderFontSize));
                                if (iError < 0)
                                {
                                    if (iError == -1)
                                    {
                                        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG," Is the Last Page!\n");
                                    }
                                    else
                                    {
                                        DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"CreatOnePage error!\n");
                                        goto exit_process;
                                    }
                                }
                            }
                        }
                        else
                        {
                            /*计算当前页第一个图标索引值*/
                            g_iStartIndex += g_iDirFileNumPerCol * g_iDirFileNumPerRow;
                            if (g_iStartIndex < g_iDirContentsNumber)
                            {
                                iError = GenerateReaderPageDirAndFile(g_iStartIndex, g_iDirContentsNumber, g_aptDirContents, ptPageVideoMem);
                            }
                            else
                            {
                                g_iStartIndex -= g_iDirFileNumPerCol * g_iDirFileNumPerRow;
                            }
                        }
                        break;
                    }
                    case 5: /*delete键*/
                    {
                        while (iSelectedFileNum)
                        {
                            iSelectedFileNum--;
                            iDirFileContentIndex = g_iStartIndex + (iSelectedFileIndex[iSelectedFileNum] - TXT_ICON_INDEX_BASE) / 2;
                            snprintf(strTmp, 256, "%s/%s", g_strCurDir, g_aptDirContents[iDirFileContentIndex]->strName);
                            strTmp[255] = '\0';
                            iError = remove(strTmp);
                            if (iError < 0)
                            {
                                DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"can't remove %s\r\n", strTmp);
                            }
                            DBG_PRINTF(DLOG_LVL_INFO,DLOG_TAG,"remove %s success!\r\n", strTmp);
                        }
                        InvertButton(&g_atMenuIconsLayout[iIndexPressed],ptPageVideoMem);
                        ReloadFileIcons(ptPageVideoMem);
                        break;
                    }
                    default:
                    {
                        break;
                    }
                    }
                }
            }
            else     /*按下的是文件或目录*/
            {
                /*按下和松开的不是同一个图标*/
                if (iIndexPressed != iIndex)
                {
                    /*释放被选择文件或目录*/
                    SelectDirFileIcon(iIndexPressed - TXT_ICON_INDEX_BASE,ptPageVideoMem);
                }
                else if(iSelectFlag)
                {
                    iSelectedFileIndex[iSelectedFileNum] = iIndex;
                    iSelectedFileNum++;
                    goto mouse;
                }
                else
                { /*单击目录进入 */
                    SelectDirFileIcon(iIndexPressed - TXT_ICON_INDEX_BASE,ptPageVideoMem);

                    iDirFileContentIndex = g_iStartIndex + (iIndexPressed - TXT_ICON_INDEX_BASE) / 2;

                    /*判断文件类型，图片or文本*/
                    switch (g_aptDirContents[iDirFileContentIndex]->eFileType)
                    {
                    case FILETYPE_FILE_TXT:
                        /*显示TXT文件*/
                        snprintf(strTmp, 256, "%s/%s", g_strCurDir, g_aptDirContents[iDirFileContentIndex]->strName);
                        strTmp[255] = '\0';
                        if(!g_pucFileStart)
                        {    
                            EnterCurTXTFile(ptPageVideoMem,strTmp);          
                        }

                        break;
                    case FILETYPE_FILE_BMP:
                    case FILETYPE_FILE_JPEG:
                    case FILETYPE_FILE_PNG:
                        break;
                    case FILETYPE_FILE_DEFAULT:
                        /*默认*/
                        break;
                    default:
                        break;
                    }
                }
            }
        }
        else     /*按键被按下*/
        {
            if (iIndex == -1)   /*事件无效*/
            {
                goto mouse;
            }
            if (!bIconPressed) /*没有文件被按下*/
            {
                bIconPressed = 1;
                iIndexPressed = iIndex;
                tInputEventPrePress = tInputEvent;
                /*菜单栏按钮被选择*/
                if (iIndex < TXT_ICON_INDEX_BASE)
                {
                    if(iIndex == 1)
                    {
                        goto mouse;
                    }
                    InvertButton(&g_atMenuIconsLayout[iIndex],ptPageVideoMem);
                }
                else
                {
                    SelectDirFileIcon(iIndex - TXT_ICON_INDEX_BASE,ptPageVideoMem);
                }
            }
            if (iIndexPressed == 0) /* 长按"向上"按钮退出*/
            {
                if (TimeMSBetween(tInputEventPrePress.tTime, tInputEvent.tTime) > 2000)
                {
                    FreeDirContents(g_aptDirContents, g_iDirContentsNumber);
                    goto exit_process;
                }
            }
        }
    mouse:
        FlushVideoMemToDev(ptPageVideoMem);
        MergeMouseToDisp(&tInputEvent, ptDevVideoMem);
    }
exit_process:
    PutVideoMem(ptPageVideoMem);
}

/**
 * @brief 电子书阅读页面结构体
*/
static T_PageAction g_tReaderPageAction = {
    .name = "reader",
    .Run = ReaderPageRun,
    .GetInputEvent = ReaderPageGetInputEvent,
    //.Prepare       = ReaderPagePrepare;
};

/* Public Function Prototypes ------------------------------------------------*/

/**
 * @brief 电子书阅读页面注册函数
 * 
 * @return int 成功：0;失败：其他
*/
int ReaderPageInit(void)
{
    return RegisterPageAction(&g_tReaderPageAction);
}
